package org.unikn.dbvis.net;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * XQuery test class.
 *
 * @author Workgroup DBIS, University of Konstanz 2005-09, ISC License
 * @author Christian Gruen
 */
public final class BaseXConnection {
  /** Process reference. */
  private String proc;
  /** Host name. */
  private final String host;
  /** Port number. */
  private final int port;
  /** Temporary socket instance. */
  private Socket socket;
  /** Last socket reference. */
  private int last;

//  public static void main(String[] args) throws Exception {
//    BaseXConnection test =
//      new BaseXConnection("localhost", 1984, "xquery doc('input')//li");
//    if(test.execute()) {
//      String result = test.output();
//      System.out.println(result);
//    }
//  }

  public String getResult()
  {
	  try {
		this.execute();
		return this.output();

	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}		
	return " ";

	  
  }
  
  /**
   * Constructor, specifying the server host:port and the command to be sent.
   * @param h name of the host
   * @param p port
   * @param pr process
   */
  public BaseXConnection(final String h, final int p, final String pr) {
    host = h;
    port = p;
    proc = pr;
  }
  
  public boolean execute() throws IOException {
    send(proc);
    last = new DataInputStream(socket.getInputStream()).readInt();
    return last > 0;
  }

  public String output() throws IOException {
    send("getresult " + last);
    return receive();
  }

  public String info() throws IOException {
    send("getinfo " + last);
    return receive();
  }

  /**
   * Sends the specified command and argument over the network.
   * @param command command to be sent
   * @throws IOException I/O Exception
   */
  private void send(final String command) throws IOException {
    socket = new Socket(host, port);
    new DataOutputStream(socket.getOutputStream()).writeUTF(command);
  }

  /**
   * Receives an input stream over the network.
   * @throws IOException I/O Exception
   */
  private String receive() throws IOException {
    final InputStream in = socket.getInputStream();
    final byte[] bb = new byte[4096];
    int l = 0;
    
    StringBuilder sb = new StringBuilder();
    while((l = in.read(bb)) != -1) {
      for(int i = 0; i < l; i++) {
        sb.append((char) bb[i]);
      }
    }
    return sb.toString();
  }
}
